/*
 * Copyright 2013 Nicholas Bilyk
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package jasper.model.elements;

import jasper.model.IMarshallable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.xml.stream.events.Namespace;
import java.util.Arrays;
import java.util.Vector;

/**
 * The base class for all xml nodes in a schema definition.
 *
 * @author nbilyk
 */
public abstract class SchemaNode implements IMarshallable {

	public static final String DEFAULT_NAMESPACE = "http://www.w3.org/2001/XMLSchema";

	/**
	 * The Element's namespace
	 */
	protected Namespace namespace;

	/**
	 * Child elements.
	 */
	protected Vector<SchemaNode> elements = new Vector<SchemaNode>();

	/**
	 * A list of the possible parents to which this element can belong.
	 */
	protected Class[] allowedParents;

	/**
	 * Sets the element's parent.
	 * @param parent The new parent.
	 */
	protected void setParent(SchemaNode parent) {
		if (allowedParents != null) {
			Boolean allowed = Arrays.asList(allowedParents).contains(parent.getClass());
			if (!allowed) {
				throw new IllegalArgumentException("Cannot add a child of type " + getClass() +
						" to a parent of type " + parent.getClass());
			}
		}
	}

	/**
	 * Adds a child to the child element list.
	 * @param child The child to add.
	 */
	public void addChild(SchemaNode child) {
		child.setParent(this);
		elements.add(child);
	}

	@Override
	public void marshal(Document document, Element element) {
		element.setAttribute("Foo", "Bar");

		for (SchemaNode childNode : elements) {
			Element child = document.createElementNS(DEFAULT_NAMESPACE, "blah");
			childNode.marshal(document, child);
			element.appendChild(child);
		}
	}
}
